package cn.biplam.back.services.sequence;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import cn.biplam.back.jda.Jda;
import cn.biplam.common.bean.sqlengine.Sql;
import cn.biplam.common.client.DbResource;
import cn.biplam.common.interfaces.SequenceServer;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.ErrorMessage;
import cn.biplam.common.wrapper.sqlresult.SqlResult;

/**
 * 生成记录序列号服务
 * @author XiaoRuxing 2009-5-15下午04:48:25
 * @version 1.0
 */
public class SequenceServerImpl extends UnicastRemoteObject implements SequenceServer{

	/** */
	private static final long serialVersionUID = 2045689963146225156L;
	private Lock mLock=new ReentrantLock();
	private int iCount=0;
	
	public SequenceServerImpl() throws RemoteException{
		iCount++;
	}

	/**
	 * 获取表记录在系统的唯一编号
	 * @param userId    用户ID
	 * @param tableName 表名
	 * @return 返回序号 用户ID+表序号+当前所有表记录总序号
	 * @throws RemoteException
	 * @throws ErrorMessage
	 */
	public synchronized String getSequence(String userId)	throws RemoteException, ErrorMessage {
		addCount();
		String sequenceNum=null;
		SqlResult sr = null;
		StringBuilder sp=new StringBuilder();
		try{
			_updateSequence();
			Jda mJda = new Jda(new DbResource(DbResource.RT));
			sp.append("select sequence_numb from  sequence 	");  
			sr=mJda.executeSelect(new Sql(sp.toString()));
			sequenceNum = sr.get(0, 0);
			sequenceNum = Integer.toHexString(TOOLS.stringToInt(sequenceNum));
		}catch(ErrorMessage e){
			throw e;
		}catch(Exception e){
			ErrorMessage mErrorMessage = new ErrorMessage(e);
			throw mErrorMessage;
		}finally{
			reduceCount();
		}
		return sequenceNum;
	}

	private boolean _updateSequence() throws ErrorMessage{
		Jda mJda = new Jda(new DbResource(DbResource.RT));
		StringBuilder sp=new StringBuilder();
		sp.append("update sequence 						 ");  
		sp.append("set sequence_numb=sequence_numb+1 ");  
		return mJda.executeDML(new Sql(sp.toString()));
	}
	
	/**
	 * 取当前运行实例个数
	 * @return 当前运行实例
	 * @throws RemoteException
	 */
	public int getCount() throws RemoteException {
		return this.iCount;
	}

	/**
	 * 当前运行的实例个数加一
	 */
	private synchronized void addCount() {
		this.iCount++;
	}

	/**
	 * 当前运行的实例个数减一
	 */
	private synchronized void reduceCount() {
		this.iCount--;
	}

	/**
	 * 加锁
	 * @throws RemoteException
	 */
	public void lock() throws RemoteException {
		mLock.lock();
	}

	/**
	 * 加锁
	 * @return
	 * @throws RemoteException
	 */
	public boolean trylock() throws RemoteException {
		return mLock.tryLock();
	}

	/**
	 * 解锁
	 * @throws RemoteException
	 */
	public void unlock() throws RemoteException {
		mLock.unlock();
	}
	
}
